package com.diamondsys.embrapa;

import com.diamondsys.embrapa.util.JsfUtil;
import com.diamondsys.embrapa.util.JsfUtil.PersistAction;
import com.diamondsys.embrapa.util.RetrieveUserAttributes;
import java.io.IOException;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;

@Named("usuarioController")
@SessionScoped
public class UsuarioController implements Serializable {

    @EJB
    private com.diamondsys.embrapa.UsuarioFacade ejbFacade;
    private List<Usuario> items = null;
    private Usuario selected;

    public UsuarioController() {
        selected = new Usuario();
        initializeEmbeddableKey();
        JsfUtil.AddSessionParameter("uri", ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getRequestURI().replace(((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getPathInfo(), "/"));
    }

    public Usuario getSelected() {
        return selected;
    }

    public void setSelected(Usuario selected) {
        
        this.selected = selected;
    }

    protected void setEmbeddableKeys() {
    }

    protected void initializeEmbeddableKey() {
    }

    private UsuarioFacade getFacade() {
        return ejbFacade;
    }

    public Usuario prepareCreate() {
        selected = new Usuario();
        initializeEmbeddableKey();
        return selected;
    }
    
    public void create() {
        
        persist(PersistAction.CREATE, ResourceBundle.getBundle("/Bundle").getString("UsuarioCreated"));

        if (!JsfUtil.isValidationFailed()) {
            items = null;    // Invalidate list of items to trigger re-query.
        }
    }

    public void createCliente() {
        
        selected.setFuncao("cliente");
        selected.setId(0);
        
        persist(PersistAction.CREATE, ResourceBundle.getBundle("/Bundle").getString("UsuarioCreated"));

        if (!JsfUtil.isValidationFailed()) {
            items = null;    // Invalidate list of items to trigger re-query.
        }
    }    
    
    public void update() {
        persist(PersistAction.UPDATE, ResourceBundle.getBundle("/Bundle").getString("UsuarioUpdated"));
    }

    public void destroy() {
        persist(PersistAction.DELETE, ResourceBundle.getBundle("/Bundle").getString("UsuarioDeleted"));
        if (!JsfUtil.isValidationFailed()) {
            selected = null; // Remove selection
            items = null;    // Invalidate list of items to trigger re-query.
        }
    }

    public List<Usuario> getItems() {
        if (items == null) {
            items = getFacade().findAll();
        }
        return items;
    }

    public List<Usuario> findWithLogin(String login) {
        return getFacade().getEntityManager().createNamedQuery("Usuario.findByLogin", Usuario.class)
                .setParameter("login", login)
                .getResultList();
    }

    
    private void persist(PersistAction persistAction, String successMessage) {
        if (selected != null) {
            setEmbeddableKeys();
            try {
                if (persistAction != PersistAction.DELETE) {
                    
                    boolean encryptSenha = true;
                    if (persistAction == PersistAction.UPDATE && (selected.getSenha() == null || selected.getSenha().trim().length() < 1))
                    {
                        Usuario usuarioExistente = this.getUsuario(selected.getId());

                        if (!(usuarioExistente.getLdap().toString().equals("S") && selected.getLdap().toString().equals("N"))) 
                        {
                            this.selected.setSenha(usuarioExistente.getSenha());
                            encryptSenha = false;
                        }
                    }
                    
                    if (!selected.getLdap().toString().equals("S") && (selected.getSenha() == null || selected.getSenha().trim().length() < 5))
                    {
                        JsfUtil.addWarningMessage("A senha deve possuir ao menos 5 caracteres");
                        FacesContext.getCurrentInstance().validationFailed();
                        JsfUtil.setValidationFailed();
                        return;
                    }
                    else if (selected.getLdap().toString().equals("S") && (selected.getSenha() == null || selected.getSenha().trim().length() < 1))
                    {
                        selected.setSenha(" ");
                    }
                        
                    List<Usuario> usuarios = this.findWithLogin(selected.getLogin());

                    if ( usuarios == null || usuarios.isEmpty() || Objects.equals(usuarios.get(0).getId(), selected.getId())){
                    
                        
                        if(encryptSenha) selected.setSenha(JsfUtil.encryptMD5(selected.getSenha())); 

                        getFacade().edit(selected);
                    } else {
                        JsfUtil.addWarningMessage("O Login informado já está em uso!");
                        FacesContext.getCurrentInstance().validationFailed();
                        return;
                    }                    

                } else {
                    getFacade().remove(selected);
                }
                JsfUtil.addSuccessMessage(successMessage);
            } catch (EJBException ex) {
                String msg = "";
                Throwable cause = ex.getCause();
                if (cause != null) {
                    msg = cause.getLocalizedMessage();
                }
                if (msg.length() > 0) {
                    JsfUtil.addErrorMessage(msg);
                } else {
                    JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
                }
            } catch (Exception ex) {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
                JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            }
        }
    }

    public Usuario getUsuario(java.lang.Integer id) {
        return getFacade().find(id);
    }

    public List<Usuario> getItemsAvailableSelectMany() {
        return getFacade().findAll();
    }

    public List<Usuario> getItemsAvailableSelectOne() {
        return getFacade().findAll();
    }

    public void Ldap() throws IOException, NamingException {
      
        if (new RetrieveUserAttributes().getUserBasicAttributes(selected.getLogin(), selected.getSenha()))
        {
            JsfUtil.addSuccessMessage("Usuário econtrado no LDAP");
        }
        else
        {
            JsfUtil.addWarningMessage("Usuário não encontrado no LDAP");
        }
        
    }
    
    public void LdapSenha() throws IOException, NamingException {
      
        if (new RetrieveUserAttributes().conectarSenha(selected.getLogin(), selected.getSenha()))
        {
            JsfUtil.addSuccessMessage("Conexão LDAP efetuada");
        }
        else
        {
            JsfUtil.addWarningMessage("Conexão LDAP não efetuada");
        }
        
    }    
    
    public void Login() throws IOException {
        
        Boolean loggedLDAP=false;

        List<Usuario> usuarios = this.findWithLogin(selected.getLogin());
                
        if (usuarios != null && !usuarios.isEmpty() && usuarios.get(0).getLdap().toString().toLowerCase().equals("s"))
        {
            loggedLDAP = new RetrieveUserAttributes().conectarSenha(selected.getLogin(), selected.getSenha());
        }
        
        if ((selected.getLogin().equals("admin") && selected.getSenha().equals("2015EmbrapaGrito")) || loggedLDAP || (usuarios != null && !usuarios.isEmpty() && usuarios.get(0).getSenha().equals(JsfUtil.encryptMD5(selected.getSenha()))))
        {
            ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
            Map<String, Object> sessionMap = externalContext.getSessionMap();
            
            if (selected.getLogin().equals("admin"))
            {
                selected.setFuncao("Administrador");
                selected.setId(1);
                sessionMap.put("user", selected);
            }
            else
            {
                sessionMap.put("user", usuarios.get(0));
            }
            
            
            this.selected = new Usuario();
            
            String uri = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getRequestURI();
            String fileName = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getPathInfo();
            
            FacesContext.getCurrentInstance().getExternalContext().redirect(uri.replace(fileName, "/sistemas/mural.xhtml"));
        }
        else
        {
            JsfUtil.addSuccessMessage("Usuário ou senha inválido");
        }
    }
    
    public void Logout() throws IOException {
        JsfUtil.AddSessionParameter("user",null);
        String uri = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getRequestURI();
        String fileName = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getPathInfo();
        FacesContext.getCurrentInstance().getExternalContext().redirect(uri.replace(fileName, "/login/Login.xhtml"));
    }
   
    public void NavegarHome() throws IOException {
        String uri = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getRequestURI();
        String fileName = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getPathInfo();
        FacesContext.getCurrentInstance().getExternalContext().redirect(uri.replace(fileName, "/sistemas/mural.xhtml"));
    }
   
    public void NavegarUser() throws IOException {
        String uri = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getRequestURI();
        String fileName = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getPathInfo();
        FacesContext.getCurrentInstance().getExternalContext().redirect(uri.replace(fileName, "/usuario/View.xhtml"));
    }
   
    public void NavegarHelp() throws IOException {
        String uri = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getRequestURI();
        String fileName = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getPathInfo();
        FacesContext.getCurrentInstance().getExternalContext().redirect(uri.replace(fileName, "/sistemas/Help.xhtml"));
    }
   
    public void TestaLogin() throws IOException {
        if (JsfUtil.GetSessionParameter("user") == null){
            String uri = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getRequestURI();
            String fileName = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getPathInfo();
            FacesContext.getCurrentInstance().getExternalContext().redirect(uri.replace(fileName, "/login/Login.xhtml"));         
        }
    }

    @FacesConverter(forClass = Usuario.class)
    public static class UsuarioControllerConverter implements Converter {

        @Override
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            UsuarioController controller = (UsuarioController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "usuarioController");
            return controller.getUsuario(getKey(value));
        }

        java.lang.Integer getKey(String value) {
            java.lang.Integer key;
            key = Integer.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Integer value) {
            StringBuilder sb = new StringBuilder();
            sb.append(value);
            return sb.toString();
        }

        @Override
        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Usuario) {
                Usuario o = (Usuario) object;
                return getStringKey(o.getId());
            } else {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "object {0} is of type {1}; expected type: {2}", new Object[]{object, object.getClass().getName(), Usuario.class.getName()});
                return null;
            }
        }

    }

}
